package mop.domain.project;

import java.util.LinkedList;
import java.util.List;

import mop.domain.task.Task;
import mop.exception.IllegalAddTaskException;
import mop.exception.IllegalDescriptionException;

/**
 * Class for Project.
 * 
 * @invar 	description is valid.
 *  		| hasValidDescription()
 *  
 * @author	MOP Team 7
 */
public class Project 
{
	
	/**
	 * Creates a Project with a description.
	 * 
	 * @param 	description
	 *  		The description of the project.
	 *  
	 * @effect 	Sets the description.
	 *       
	 * @throws 	IllegalDescriptionException
	 * 			if the description isn't a non-empty string
	 * 			| !isValidDescription(description)
     *       
	 */
	public Project(String description) 
		throws IllegalDescriptionException
	{
		this.setDescription(description);
		this.tasks = new LinkedList<Task>();
	}
	
	
	/***************************************************************************
	 * 							Project description
	 ***************************************************************************/
	
	/**
	 * Returns the description for this project.
	 * 
	 * @return 	description;
	 */
	public String getDescription()
	{
		return this.description;
	}
	
	 /**
	  * Checks if the passed description is ok.
	  * 
	  * @param 	description
	  *  		The description you want checked.
	  * 
	  * @return true if the passed description is not empty and it's not null.
	  */
	 public static boolean isValidDescription(String description)
	 {
		 return ((!(description.trim().equals("")) && description != null));
	 }
	
	 /**
	  * Set the descriptions
	  * 
	  * @param 	description
	  *  		The description for the project.
	  *  
	  * @post 	The description is set.
	  *  
	  * @throws IllegalDescriptionException 
	  *       	if the description isn't ok
	  *       	| !isValidDescription(description)
	  *    
	  */
	 private void setDescription(String description) throws IllegalDescriptionException
	 {

		 if(!isValidDescription(description))
		 {
			 throw new IllegalDescriptionException(description);
		 }
		 this.description = description;

	 }
	
	 /**
	  * Variable for the description of the project.
	  */
	private String description;
	
	
	/***************************************************************************
	 * 						Tasks
	 ***************************************************************************/
	
	/**
	 * Adds a task to the project.
	 * If the task is already assigned to another project: throw exception.
	 * 
	 * @param 	task
	 * 			The task to be added.
	 * 
	 * @throws 	IllegalAddTaskException
	 *  		if the task already has a project
	 *  		| task.getproject != null
	 */
	public void addTask(Task task) throws IllegalAddTaskException
	{
		if(task.getProject() == null)
		{
			tasks.add(task);
			task.setProject(this);
		}
		else
		{
			throw new IllegalAddTaskException();
		}
	}
	
	/**
	 * Returns the tasks in a list of strings (descriptions).
	 * 
	 * @return	this.tasks.getDescription
	 */
	public List<String> getTasks()
	{
		List<String> tasks_str = new LinkedList<String>();
		for(Task t : tasks)
		{
			tasks_str.add(t.getDescription());
		}
		
		return tasks_str;
	}
	
	/**
	 * Variable to hold the tasks associated with the project
	 */
	private List<Task> tasks = null;
	
	
	/***************************************************************************
	 * 						Java Object interface
	 ***************************************************************************/
	
	/**
	 * Returns a String representing the project.
	 * 
	 * @return	A string with on the first line this.getDescription
	 */
	public String toString()
	{
		return this.getDescription();
	}
	
	/***************************************************************************
	 * 						       Termination
	 ***************************************************************************/
	
	/**
	 * Destroys a project .
	 * 
	 * @effect	Terminates and removes all tasks in the list.
	 */
	public void terminate()
	{
		if(tasks == null) return;
		for(Task t : tasks)
		{
			t.terminate(true); // a huge domino effect of destructions may occur.
		}
		tasks = null; // clear in one move
	}
	
}